package myProj1;

import java.util.Random;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import myProj1.Player;
import myProj1.Date;

public class Project1 {

	public static final int SEED = 123;
	static Player p1;
	static Player p2;

	/**
	 * coin flips 1 for head and 0 for tail
	 * 
	 * @param ranBook
	 * @return
	 */
	public static int coinflips(Random ranBook) {
		int coinFlips; // seed
		coinFlips = ranBook.nextInt(2);
		return coinFlips;
	}

	/**
	 * is str a Numeric
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumeric(String str) {
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if (!isNum.matches()) {
			return false;
		}
		return true;
	}

	public static void main(String[] args) {
		Date finalDate = new Date("Dec", 31);
		Player currentPlayer = null;
		Scanner scanner = new Scanner(System.in);
		Random random = new Random(SEED);
		p1 = new Player();
		p2 = new Player();

		int game = 1;// game round number
		int turn = 1;// turn round number
		String inputName1;
		String inputName2;
		do { // do while for enter name of person1
			System.out.print("Enter name for one of the players");
			inputName1 = scanner.nextLine();
		} while (inputName1.length() == 0);
		p1.setName(inputName1);
		do { // do while for enter name of person2
			System.out.print("Enter a different name for the oppoent:");
			inputName2 = scanner.nextLine();
		} while (inputName2.length() == 0 || inputName2.equals(inputName1));
		p2.setName(inputName2);

		boolean startFlag = true;
		// game start
		while (startFlag) {
			// coin toss begin
			System.out.print(p1.getName() + " call Heads or Tails to determine starting player:");
			String coinDecition = scanner.nextLine();
			int headsTailsNum=coinflips(random);
			if (coinDecition.equals("")) {
				continue;
			} else if ((coinDecition.charAt(0) + "").equalsIgnoreCase("H")) {

				if (headsTailsNum == 1) {
					System.out.println("It came up Heads! You win the coin toss");

					currentPlayer = p1;
				} else {
					System.out.println("It came up Tails! You lost the coin toss");

					currentPlayer = p2;
				}
			} else if ((coinDecition.charAt(0) + "").equalsIgnoreCase("t")) {

				if (headsTailsNum == 0) {
					System.out.println("It came up Tails! You win the coin toss");

					currentPlayer = p1;
				} else {
					System.out.println("It came up Heads! You lost the coin toss");

					currentPlayer = p2;
				}
			} else {
				continue;
			}
			String[] dateArray = null;
			int dateTypein = 0;
			Date prevDate = null;
			boolean end = false;
			Date datep1Typein = null;
			System.out.println("\nThis is game number " + game);
			while (!end) {
				if (currentPlayer.getCurrStrikes() == 3) {
					System.out.println("Game#" + game + " is over: " + currentPlayer.getName() + " lost on turn " + turn
							+ " because of 3 strikes");
					if (currentPlayer.equals(p1)) {
						p2.setGamesWon(p2.getGamesWon() + 1);
						p1.setCurrStrikes(0);
						p2.setCurrStrikes(0);
						System.out.println("The running total of games won so far is:");
						System.out.println(p1.getName() + "=" + p1.getGamesWon());
						System.out.println(p2.getName() + "=" + p2.getGamesWon());
						end = true;
						break;
					} else {
						p1.setGamesWon(p1.getGamesWon() + 1);
						p1.setCurrStrikes(0);
						p2.setCurrStrikes(0);
						System.out.println("The running total of games won so far is:");
						System.out.println(p1.getName() + "=" + p1.getGamesWon());
						System.out.println(p2.getName() + "=" + p2.getGamesWon());
						end = true;
						break;
					}
				}
				// coin toss end

				// enter date
				boolean dateFlag = true;

				while (dateFlag) {
					boolean ok = true;

					System.out.print("Game#" + game + " Turn#" + turn + ": " + currentPlayer + " ("
							+ currentPlayer.getCurrStrikes()
							+ " strikes), enter a month followed by a space then a date:");
					String dateStr = scanner.nextLine();

					if (dateStr.equals("")) {
						System.out.println("No entry detected");
						continue;
					}

					dateArray = dateStr.split(" ");
					if (dateArray[0].length() < 3) {
						System.out.println("Entry must be at least 3 letters to determine month.");
						ok = false;
					}

					if (dateArray.length < 2) {
						System.out.println("You did not make a second entry for the date");
						ok = false;

					}
					if (dateArray.length > 2) {
						System.out.println("Only two entries needed. Ignoring additional input");
						String[] tmp = dateArray;
						dateArray = new String[2];
						dateArray[0] = tmp[0];
						dateArray[1] = tmp[1];
					}
					if (dateArray[0].length() >= 3 && !Date.mapMonth.containsKey(dateArray[0].substring(0, 3))) {
						System.out.println("the first 3 letters \"" + (dateArray[0].charAt(0) + "").toUpperCase()
								+ dateArray[0].substring(1, 3) + "\" don't match a known month ");
						ok = false;
					}

					if (dateArray.length >= 2 && (!isNumeric(dateArray[1]))) {
						System.out.println("The second entry, the date, must be a number");
						ok = false;
					}

					if (dateArray.length >= 2 && (isNumeric(dateArray[1])) && (!isValidDate(dateArray))) {
						System.out.println("Your entry date of " + dateArray[1] + " is not between 1 and "
								+ Date.getDaysOfMonth(dateArray[0].substring(0, 3)) + " the number of days in"
								+ (dateArray[0].charAt(0) + "").toUpperCase() + dateArray[0].substring(1, 3));
						ok = false;

					}

					if (prevDate != null) {
						Date tmp = new Date(dateArray[0].substring(0, 3), Integer.parseInt(dateArray[1]));
						if (tmp.after(prevDate)) {
							if ((!prevDate.getMonth().equalsIgnoreCase(tmp.getMonth()))
									&& tmp.getDate() != prevDate.getDate()) {
								Player p = currentPlayer.equals(p1) ? p2 : p1;
								System.out.println("if choosing a month other than " + prevDate.getMonth()
										+ ", then it must have a date of " + prevDate.getDate() + " the same date as "
										+ p + " chose last turn");
								currentPlayer.setCurrStrikes(currentPlayer.getCurrStrikes() + 1);
								System.out.println(currentPlayer.getName() + ", you now have "
										+ currentPlayer.getCurrStrikes() + " strikes");
								System.out.println(p + " chose " + prevDate.toString() + " last turn");
								ok = false;
							}

						} else {
							Player p = currentPlayer.equals(p1) ? p2 : p1;
							System.out.println("you must chose a date later than " + prevDate.toString());
							currentPlayer.setCurrStrikes(currentPlayer.getCurrStrikes() + 1);
							System.out.println(currentPlayer.getName() + ", you now have "
									+ currentPlayer.getCurrStrikes() + " strikes");
							System.out.println(p + " chose " + prevDate.toString() + " last turn");
							ok = false;
						}
					}
					if (ok) {
						dateFlag = false;
					}

				}

				// enter date end

				datep1Typein = new Date(dateArray[0].substring(0, 3), Integer.parseInt(dateArray[1]));
				if (prevDate == null) {

					if (!datep1Typein.equals(new Date("Jan", 1))) {
						currentPlayer.setCurrStrikes(currentPlayer.getCurrStrikes() + 1);
						System.out.println("First player must start with Jan 1");
						System.out.println(currentPlayer.getName() + ", you now have " + currentPlayer.getCurrStrikes()
								+ " strikes");

						continue;
					} else {

						if (datep1Typein.equals(finalDate)) {
							System.out.println("Game#" + game + " is over: " + currentPlayer.getName() + " won on turn "
									+ turn + " by reaching Dec 31!");
							currentPlayer.setGamesWon(currentPlayer.getGamesWon() + 1);
							p1.setCurrStrikes(0);
							p2.setCurrStrikes(0);
							System.out.println("The running total of games won so far is:");
							System.out.println(p1.getName() + "=" + p1.getGamesWon());
							System.out.println(p2.getName() + "=" + p2.getGamesWon());
							end = true;

						} else {
							prevDate = datep1Typein;
							System.out.println(currentPlayer + " chose " + prevDate.toString() + " last turn");
							turn++;

							if (currentPlayer.equals(p1)) {
								currentPlayer = p2;
							} else {
								currentPlayer = p1;
							}
							end = false;

						}

					}
				} else {
					if (datep1Typein.equals(finalDate)) {
						System.out.println("Game#" + game + " is over: " + currentPlayer.getName() + " won on turn "
								+ turn + " by reaching Dec 31!");
						currentPlayer.setGamesWon(currentPlayer.getGamesWon() + 1);
						p1.setCurrStrikes(0);
						p2.setCurrStrikes(0);
						System.out.println("The running total of games won so far is:");
						System.out.println(p1.getName() + "=" + p1.getGamesWon());
						System.out.println(p2.getName() + "=" + p2.getGamesWon());
						end = true;

					} else {
						prevDate = datep1Typein;
						System.out.println(currentPlayer + " chose " + prevDate.toString() + " last turn");
						turn++;

						if (currentPlayer.equals(p1)) {
							currentPlayer = p2;
						} else {
							currentPlayer = p1;
						}
						end = false;

					}
				}

			}
			System.out.println("Do you wish to play again (Y/N)? ");
			String choose = scanner.nextLine();
			while (choose.equals("") || (!(choose.charAt(0) + "").equalsIgnoreCase("y")
					&& !(choose.charAt(0) + "").equalsIgnoreCase("n"))) {
				System.out.println("Do you wish to play again (Y/N)? ");
				choose = scanner.nextLine();
			}
			if ((choose.charAt(0) + "").equalsIgnoreCase("n"))
				break;
			game++;
		}

	}

	private static boolean isValidDate(String[] dateArray) {
		String tmp = dateArray[0].substring(0, 3);
		if (Date.mapMonth.get(tmp) == 1 || Date.mapMonth.get(tmp) == 3 || Date.mapMonth.get(tmp) == 5
				|| Date.mapMonth.get(tmp) == 7 || Date.mapMonth.get(tmp) == 8 || Date.mapMonth.get(tmp) == 10
				|| Date.mapMonth.get(tmp) == 12) {
			if (Integer.parseInt(dateArray[1]) > 0 && Integer.parseInt(dateArray[1]) <= 31)
				return true;

		} else if (Date.mapMonth.get(tmp) == 4 || Date.mapMonth.get(tmp) == 6 || Date.mapMonth.get(tmp) == 9
				|| Date.mapMonth.get(tmp) == 11) {
			if (Integer.parseInt(dateArray[1]) > 0 && Integer.parseInt(dateArray[1]) <= 30)
				return true;

		} else if (Date.mapMonth.get(tmp) == 2) {
			if (Integer.parseInt(dateArray[1]) > 0 && Integer.parseInt(dateArray[1]) <= 28)
				return true;

		}
		return false;
	}

}
